Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 skin-theme-clientpref-day vector-sticky-header-enabled" lang="de" dir="ltr"><head>
<meta charset="UTF-8">
<title>Multimethode</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./_res_/favicon.png">
<link rel="canonical" href="https://de.wikipedia.org/wiki/Multimethode"> <link href="./_mw_/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.math.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link href="./_mw_/ext.gadget.citeRef.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.defaultPlainlinks.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonHide.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonLayout.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonStyle.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiDarkmode.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiResponsive.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.specialSearch.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="./_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="./_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="./_res_/footer.css">
<link rel="stylesheet" type="text/css" href="./_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Multimethode rootpage-Multimethode skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">Multimethode</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="de" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="de" dir="ltr"><p>Als <b>Multimethoden</b> bezeichnet man <a href="Methode_(Programmierung)" title="Methode (Programmierung)">Methoden</a> einer <a href="Objektorientierte_Programmiersprache" class="mw-redirect" title="Objektorientierte Programmiersprache">objektorientierten Programmiersprache</a>, deren Auswahl nicht nur anhand des <a href="Datentyp" title="Datentyp">Typs</a> <i>eines</i> Objekts getroffen wird, sondern anhand der <a href="Dynamische_Bindung" title="Dynamische Bindung">dynamischen Typen</a> <i>mehrerer</i> Objekte. Diese Art der Methodenauswahl wird auch als <b><span lang="en">multiple dispatch</span></b> (‚mehrfache Verteilung‘) bezeichnet.
</p><p>Ein ähnliches Konzept wie die mehrfache Verteilung ist das in vielen prozeduralen Programmiersprachen möglichen <a href="%C3%9Cberladen" title="Überladen">Überladen</a>, bei der Methoden <a href="Polymorphie_(Programmierung)" title="Polymorphie (Programmierung)">polymorph</a> bezüglich der statischen Typen ihrer Parameter sind. Der Unterschied ist, dass das Überladen bereits zur Übersetzungszeit stattfindet, die mehrfache Verteilung jedoch erst zur Laufzeit.
</p><p>Während bei klassischen objektorientierten Sprachen wie <a href="Java_(Programmiersprache)" title="Java (Programmiersprache)">Java</a> ausschließlich der dynamische Typ des impliziten ersten Parameters <code>this</code> herangezogen wird, können in Sprachen mit <i>multiple dispatch</i> Methoden auch auf die dynamischen Typen aller ihrer <a href="Parameter_(Informatik)" title="Parameter (Informatik)">Parameter</a> spezialisiert werden. Die von vielen (insbesondere <a href="C_(Programmiersprache)" title="C (Programmiersprache)">C</a>-ähnlichen) kompilierten Sprachen angebotene Überladung entspricht einem <i>multiple dispatch</i> zur Übersetzungszeit. Interessanterweise bieten die meisten Skriptsprachen Multimethoden in Form von Überladung jedoch zu Gunsten <a href="Dynamische_Typisierung" title="Dynamische Typisierung">dynamischer Typisierung</a> nicht an. Allerdings schließt dynamische Typisierung Multimethoden nicht aus.
</p><p>Die erste und bekannteste objektorientierte Umgebung, die diese Fähigkeit hat, ist das <a href="Common_Lisp_Object_System" title="Common Lisp Object System">Common Lisp Object System</a> (CLOS),<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> aber auch Sprachen wie <a href="Dylan_(Programmiersprache)" title="Dylan (Programmiersprache)">Dylan</a>, <a href="Slate_(Programmiersprache)" title="Slate (Programmiersprache)">Slate</a>, Cecil, <a href="Guile" class="mw-redirect" title="Guile">Guile</a>, <a href="Seed7" title="Seed7">Seed7</a>, <a href="Julia_(Programmiersprache)" title="Julia (Programmiersprache)">Julia</a> oder der Java-Abkömmling <a href="Nice_(Programmiersprache)" title="Nice (Programmiersprache)">Nice</a> bieten Derartiges. In <a href="C%2B%2B" title="C++">C++</a> ist es möglich, Multimethoden als <a href="Funktionsobjekt" class="mw-redirect" title="Funktionsobjekt">Funktoren</a> und <a href="Template_(Programmierung)" class="mw-redirect" title="Template (Programmierung)">Templates</a> auf verschiedene Weisen zu implementieren. In der <a href="Java_Virtual_Machine" title="Java Virtual Machine">JVM</a> Welt ist z.&nbsp;B. <a href="Groovy" title="Groovy">Groovy</a> eine Java-Syntax-kompatible Sprache mit größerer Verbreitung, die (sowohl bei dynamischer als auch statischer Kompilierung) standardmäßig Multimethoden unterstützt.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p>

<div class="mw-heading mw-heading2"><h2 id="Multimethoden_in_Common_Lisp">Multimethoden in Common Lisp</h2></div>
<p>Die objektorientierte Programmierung mit Multimethoden unterscheidet sich in einigen Punkten grundlegend von <i>eindimensionaler objektorientierter Programmierung</i>. In Common Lisp basieren Multimethoden auf drei elementaren Konzepten, die anders zu verstehen sind als z.&nbsp;B. in Java:
</p>
<ul><li>Klassen: Sie werden immer <i>ohne</i> eigene Methoden definiert. Zur Klassendefinition gehört nur die Liste der Superklassen und die Liste ihrer Slots (= „Membervariablen“). Auch später können der Klassendefinition keinerlei Methoden hinzugefügt werden.</li>
<li>Generische Funktionen: Statt einer Klasse werden die Methoden unter einer generischen Funktion gleichen Namens zusammengefasst. Die generische Funktion ist selbst nur ein Container für die dazugehörigen Methoden.</li>
<li>Methoden: Sie kennen keinen impliziten <code>this</code>-Parameter im Sinne eines einzelnen, diese Methode aufrufenden Objekts, weil es sonst auch <code>this2</code>, <code>this3</code> usw. geben müsste. Stattdessen erscheinen alle angesprochenen Objekte wie normale Parameter in der Parameterliste der Methode.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Praktisches_Beispiel_in_Common_Lisp">Praktisches Beispiel in Common Lisp</h2></div>
<p>Das folgende Beispiel verwendet Multimethoden, um die Bildung der Schnittmenge mit drei intern unterschiedlich dargestellten Mengen interoperabel zu implementieren.
</p>
<div class="mw-heading mw-heading3"><h3 id="Mengendarstellungen">Mengendarstellungen</h3></div>
<p>Es sollen die folgenden drei Implementierungen für Mengen unterstützt werden:
</p>
<ol><li>Darstellung durch <a href="Extension_und_Intension#Intension" title="Extension und Intension">Intension</a>
<dl><dd>Hierbei ist die Elementzugehörigkeit durch ein <a href="Pr%C3%A4dikat_(Logik)" title="Prädikat (Logik)">Prädikat</a> gegeben:</dd>
<dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M:=\lbrace x|P(x)\rbrace }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
<mo>:=</mo>
<mo fence="false" stretchy="false">{</mo>
<mi>x</mi>
<mrow class="MJX-TeXAtom-ORD">
<mo stretchy="false">|</mo>
</mrow>
<mi>P</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M:=\lbrace x|P(x)\rbrace }</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/db9738ed09a3a1d625d804aeade1af64e472fd8d.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:15.373ex; height:2.843ex;" alt="{\displaystyle M:=\lbrace x|P(x)\rbrace }" loading="lazy"></span></dd>
<dd>Alle Elemente <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle x}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>x</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle x}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/87f9e315fd7e2ba406057a97300593c4802b53e4.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.33ex; height:1.676ex;" alt="{\displaystyle x}" loading="lazy"></span>, für die <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle P(x)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>P</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle P(x)}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/89833156eff2c51bfb8750db3306a0544ce34e14.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:4.884ex; height:2.843ex;" alt="{\displaystyle P(x)}" loading="lazy"></span> wahr ist, gehören zu <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/f82cade9898ced02fdd08712e5f0c0151758a0dd.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.442ex; height:2.176ex;" alt="{\displaystyle M}" loading="lazy"></span>. Die Menge kann unendlich groß sein. Die Darstellung von <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle P}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>P</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle P}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/b4dc73bf40314945ff376bd363916a738548d40a.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.745ex; height:2.176ex;" alt="{\displaystyle P}" loading="lazy"></span> erfolgt durch einen anonymen <a href="Lambda-Ausdruck" class="mw-redirect" title="Lambda-Ausdruck">Lambda-Ausdruck</a>.</dd></dl></li>
<li>Darstellung durch <a href="Extension_und_Intension#Extension" title="Extension und Intension">Extension</a>
<dl><dd>Bei dieser Darstellung werden alle Elemente der Menge aufgezählt:</dd>
<dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M:=\lbrace 2,39,{\text{HUT}},{\text{STOCK}},{\text{REGENSCHIRM}}\rbrace }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
<mo>:=</mo>
<mo fence="false" stretchy="false">{</mo>
<mn>2</mn>
<mo>,</mo>
<mn>39</mn>
<mo>,</mo>
<mrow class="MJX-TeXAtom-ORD">
<mtext>HUT</mtext>
</mrow>
<mo>,</mo>
<mrow class="MJX-TeXAtom-ORD">
<mtext>STOCK</mtext>
</mrow>
<mo>,</mo>
<mrow class="MJX-TeXAtom-ORD">
<mtext>REGENSCHIRM</mtext>
</mrow>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M:=\lbrace 2,39,{\text{HUT}},{\text{STOCK}},{\text{REGENSCHIRM}}\rbrace }</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/7412aa301a6e35e55578693f332c787bee3ae101.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:47.403ex; height:2.843ex;" alt="{\displaystyle M:=\lbrace 2,39,{\text{HUT}},{\text{STOCK}},{\text{REGENSCHIRM}}\rbrace }" loading="lazy"></span></dd></dl></li>
<li>Darstellung als Intervall
<dl><dd>Ein zusammenhängendes Intervall aus der Menge <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbb {Z} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="double-struck">Z</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbb {Z} }</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/449494a083e0a1fda2b61c62b2f09b6bee4633dc.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.55ex; height:2.176ex;" alt="{\displaystyle \mathbb {Z} }" loading="lazy"></span> bildet die Menge <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/f82cade9898ced02fdd08712e5f0c0151758a0dd.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.442ex; height:2.176ex;" alt="{\displaystyle M}" loading="lazy"></span>:</dd>
<dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M:=\lbrace 10,\dotsc ,20\rbrace }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
<mo>:=</mo>
<mo fence="false" stretchy="false">{</mo>
<mn>10</mn>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<mn>20</mn>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M:=\lbrace 10,\dotsc ,20\rbrace }</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/6125256bf96816216e25b10f404f10a7981e3625.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:18.34ex; height:2.843ex;" alt="{\displaystyle M:=\lbrace 10,\dotsc ,20\rbrace }" loading="lazy"></span></dd></dl></li></ol>
<div class="mw-heading mw-heading3"><h3 id="Programmcode">Programmcode</h3></div>
<div class="mw-heading mw-heading4"><h4 id="Klassendefinitionen">Klassendefinitionen</h4></div>
<p>Für diese drei Darstellungen werden die Klassen <code>set-by-intension</code>, <code>set-by-extension</code> und <code>integer-range-set</code> definiert. Die beiden letzteren sind von der abstrakten Klasse <code>enumeratable-set</code> abgeleitet, die ihrerseits wie <code>set-by-intension</code> von der Hauptklasse <code>any-set</code> abgeleitet ist.
</p><p>Die Beziehung der Klassen ist demnach wie folgt:
</p>
<style data-mw-deduplicate="TemplateStyles:r249237068">
/* start https://de.wikipedia.org/ */


.mw-parser-output .stammbaum td{border-color:#000000!important}@media screen{html.skin-theme-clientpref-night .mw-parser-output .stammbaum td{border-color:#ffffff!important}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .stammbaum td{border-color:#ffffff!important}}


/* end https://de.wikipedia.org/ */
</style><table class="stammbaum" style="border-collapse:collapse; text-align:center;margin:1em;">

<tbody><tr style="font-weight:normal;"><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="6" rowspan="2" style="border: 2px solid; padding: 0.2em; ;"><i><code>any-set</code></i></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="text-align:center;"></tr>

<tr style="font-weight:normal;"><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-right: 1px solid; border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2"><div style="width: 1em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="text-align:center;"><td style="border-right: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-right: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="font-weight:normal;"><td colspan="6" rowspan="2" style="border: 2px solid; padding: 0.2em; ;"><b><code>set-by-intension</code></b></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="6" rowspan="2" style="border: 2px solid; padding: 0.2em; ;"><i><code>enumerateable-set</code></i></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="text-align:center;"></tr>

<tr style="font-weight:normal;"><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-right: 1px solid; border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2" style="border-bottom: 1px solid;"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-bottom: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2"><div style="width: 1em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="text-align:center;"><td style="border-right: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="2"><div style="width: 2em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td style="border-right: 1px solid;"><div style="width: 1em; height: 1em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td></tr>
<tr style="font-weight:normal;"><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="6" rowspan="2" style="border: 2px solid; padding: 0.2em; ;"><b><code>set-by-extension</code></b></td><td rowspan="2" colspan="2"><div style="width: 2em; height: 2em;"><span style="font: 1px/1px serif;">&nbsp;</span></div></td><td colspan="6" rowspan="2" style="border: 2px solid; padding: 0.2em; ;"><b><code>integer-range-set</code></b></td></tr>
<tr style="text-align:center;"></tr>
</tbody></table>
<p>Die Umsetzung der Klassenhierarchie in Common Lisp erfolgt in fünf einzelnen Definitionen.
</p>
<div class="mw-heading mw-heading5"><h5 id="Klasse_any-set_(abstrakt)"><span id="Klasse_any-set_.28abstrakt.29"></span>Klasse any-set (abstrakt)</h5></div>
<div style="float:right; margin-left:2em; width:25%; border:1px solid #448800; padding:0.4em; background:#EEFFEE;">
<p><b>Common Lisp:</b> <code>(defclass …)</code>
</p><p>Klassen werden in Common Lisp mit <code>(defclass &lt;superclasses&gt; &lt;slot-definitions&gt;)</code> deklariert. Dabei ist &lt;superclasses&gt; die Liste der Superklassen und &lt;slot-definitions&gt; eine Liste von Slotdefinitionen.
</p>
</div>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defclass</span><span class="w"> </span><span class="nv">any-set</span><span class="w"> </span><span class="p">()</span>
<span class="w"> </span><span class="p">())</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Klasse_set-by-intension">Klasse set-by-intension</h5></div>
<p>Diese enthält nur das einstellige Prädikat <code>predicate</code> als Funktion mit Wertebereich <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \lbrace w,f\rbrace }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo fence="false" stretchy="false">{</mo>
<mi>w</mi>
<mo>,</mo>
<mi>f</mi>
<mo fence="false" stretchy="false">}</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \lbrace w,f\rbrace }</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/88f9bfb85fb1956a1ab0665557026b0474345fca.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:6.302ex; height:2.843ex;" alt="{\displaystyle \lbrace w,f\rbrace }" loading="lazy"></span>, das entscheidet, ob das ihm übergebene Argument zu <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle M}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>M</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle M}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/f82cade9898ced02fdd08712e5f0c0151758a0dd.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.442ex; height:2.176ex;" alt="{\displaystyle M}" loading="lazy"></span> gehört:
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defclass</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="w"> </span><span class="p">(</span><span class="nv">any-set</span><span class="p">)</span>
<span class="w"> </span><span class="p">((</span><span class="nv">predicate</span><span class="w"> </span><span class="ss">:accessor</span><span class="w"> </span><span class="nv">predicate</span><span class="w"> </span><span class="ss">:initarg</span><span class="w"> </span><span class="ss">:predicate</span><span class="p">)))</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Klasse_enumerateable-set_(abstrakt)"><span id="Klasse_enumerateable-set_.28abstrakt.29"></span>Klasse enumerateable-set (abstrakt)</h5></div>
<p>Ihr Zweck ist es, eine gemeinsame Elternklasse für die Klassen <code>set-by-extension</code> und <code>integer-range-set</code> als Bezugspunkt für Methodendefinitionen zur Verfügung zu haben.
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defclass</span><span class="w"> </span><span class="nv">enumerateable-set</span><span class="w"> </span><span class="p">(</span><span class="nv">any-set</span><span class="p">)</span>
<span class="w"> </span><span class="p">())</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Klasse_set-by-extension">Klasse set-by-extension</h5></div>
<div style="font-size:90%; float:right; margin-left:2em; width:25%; border:1px solid #448800; padding:0.4em; background:#EEFFEE; margin-bottom:3em;">
<p><b>Common Lisp:</b> Slot-Definitionen
</p><p>Die Definition von Slots (in Java „Membervariablen“) enthält als erstes den Namen (z.&nbsp;B. <code>ext</code>) und meistens auch den gewünschten Namen der <a href="Zugriffsfunktion" title="Zugriffsfunktion">Zugriffsfunktion</a> (getter/setter), die in Lisp „Accessor“ heißt. Meistens wird auch noch der Name des Initialisierungsargumentes hinter dem Schlüsselwort <code>:initarg</code> angegeben, der bei der Instanziierung benutzt wird, um dem Slot einen initialen Wert zuzuweisen. Im Beispielprogramm sind der Slotname, der <code>:accessor</code> und das <code>:initarg</code> immer identisch.
</p>
</div>
<p>Sie enthält nur den Slot <code>ext</code>, der eine Liste der Elemente enthält:
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defclass</span><span class="w"> </span><span class="nv">set-by-extension</span><span class="w"> </span><span class="p">(</span><span class="nv">enumerateable-set</span><span class="p">)</span>
<span class="w"> </span><span class="p">((</span><span class="nv">ext</span><span class="w"> </span><span class="ss">:accessor</span><span class="w"> </span><span class="nv">ext</span><span class="w"> </span><span class="ss">:initarg</span><span class="w"> </span><span class="ss">:ext</span><span class="p">)))</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Klasse_integer-range-set">Klasse integer-range-set</h5></div>
<p>Diese Form speichert von dem geschlossenen Ganzzahlenbereich den kleinsten Wert <code>from</code> und der größten Wert <code>to</code>.
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defclass</span><span class="w"> </span><span class="nv">integer-range-set</span><span class="w"> </span><span class="p">(</span><span class="nv">enumerateable-set</span><span class="p">)</span>
<span class="w"> </span><span class="p">((</span><span class="nv">from</span><span class="w"> </span><span class="ss">:accessor</span><span class="w"> </span><span class="nv">from</span><span class="w"> </span><span class="ss">:initarg</span><span class="w"> </span><span class="ss">:from</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">to</span><span class="w"> </span><span class="ss">:accessor</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="ss">:initarg</span><span class="w"> </span><span class="ss">:to</span><span class="p">)))</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Die_leere_Menge">Die leere Menge</h5></div>
<p>Die leere Menge <code>empty-set</code> wird als konstante Instanz der Klasse <code>set-by-extension</code> ohne Elemente konstruiert. Die Instanziierung erfolgt in Common Lisp durch die Funktion <code>make-instance</code> unter Angabe der
Klasse und des Initialisierungsargumentes, das in obiger Klassendefinition <code>:ext</code> heißt. Für dieses Argument wird hier die leere Liste <code>nil</code> übergeben.
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defvar</span><span class="w"> </span><span class="nv">empty-set</span><span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'set-by-extension</span><span class="w"> </span><span class="ss">:ext</span><span class="w"> </span><span class="no">nil</span><span class="p">))</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="Generische_Funktionen">Generische Funktionen</h4></div>
<p>Nun erfolgt die Definition der <a href="Generische_Funktion" title="Generische Funktion">generischen Funktion</a> <code>enumeration</code> für die Klasse <code>enumerateable-set</code> sowie der generischen Funktion <code>intersection2</code> für zwei Argumente vom Typ <code>any-set</code>. Generische Funktionen legen nur die <a href="Signatur_(Programmierung)" title="Signatur (Programmierung)">Signatur</a> fest, sie definieren nur den Typ der Parameter, nicht die Parameternamen und sie haben keinen Funktionskörper. Die Definitionen kündigen die Existenz von (konkreten) Methoden für die genannten oder von ihnen abgeleitete Klassen an.
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defgeneric</span><span class="w"> </span><span class="nv">enumeration</span><span class="w"> </span><span class="p">(</span><span class="nv">enumerateable-set</span><span class="p">))</span>
<span class="p">(</span><span class="nb">defgeneric</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">(</span><span class="nv">any-set</span><span class="w"> </span><span class="nv">any-set</span><span class="p">))</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="Methoden_der_generischen_Funktion_enumeration">Methoden der generischen Funktion enumeration</h4></div>
<p>Diese beiden Methoden sind noch keine Multimethoden. In Java würden sie einfach mit <code>Enumeration enumeration();</code> als Methoden einer Klasse <code>SetByExtension</code> deklariert werden. <code>enumeration</code> liefert eine Aufzählung der Elemente einer indirekten Instanz von <code>enumerateable-set</code>, also von direkten Instanzen von <code>set-by-extension</code> und <code>integer-range-set</code>.
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">enumeration</span><span class="w"> </span><span class="p">((</span><span class="nv">s</span><span class="w"> </span><span class="nv">set-by-extension</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">ext</span><span class="w"> </span><span class="nv">s</span><span class="p">))</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">enumeration</span><span class="w"> </span><span class="p">((</span><span class="nv">s</span><span class="w"> </span><span class="nv">integer-range-set</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="nv">for</span><span class="w"> </span><span class="nv">i</span><span class="w"> </span><span class="nv">from</span><span class="w"> </span><span class="p">(</span><span class="nv">from</span><span class="w"> </span><span class="nv">s</span><span class="p">)</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="p">(</span><span class="nv">to</span><span class="w"> </span><span class="nv">s</span><span class="p">)</span><span class="w"> </span><span class="nv">collect</span><span class="w"> </span><span class="nv">i</span><span class="p">))</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="Konkrete_Methoden_der_generischen_Funktion_intersection2">Konkrete Methoden der generischen Funktion intersection2</h4></div>
<div style="font-size:90%; float:right; margin-left:2em; width:25%; border:1px solid #448800; padding:0.4em; background:#EEFFEE; margin-bottom:3em;">
<p><b>Common-Lisp:</b> Funktionen und Makros
</p><p><code>(remove-if-not …)</code>
</p><p>Übernimmt eine Funktion und eine Liste. Die Funktion wird der Reihe nach auf jedes Element der Liste angewandt. Zurückgegeben wird eine neue Liste aller Elemente, für die die Funktion „wahr“ geliefert hat.
</p>
<hr>
<p><code>(intersection ...)</code>
</p><p>Bildet eine Liste mit der Schnittmenge der Elemente aller übergebenen Listen. <code>(intersection '(1 2 3) '(2 3 4))</code> liefert z.&nbsp;B. <code>'(2 3)</code>.
</p>
<hr>
<p><code>(lambda …)</code>
</p><p>Übernimmt eine Parameterliste und einen Ausdruck, in dem die in der Liste genannten Parameter vorkommen dürfen. Es liefert eine anonyme Funktion zurück, die mit einer passenden Argumentenliste gerufen werden kann und mit dieser den übergebenen Ausdruck berechnet.
</p>
</div>
<p>Die fünf Methoden der generischen Funktion <code>intersection2</code> sind sämtlich Multimethoden.
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">enumerateable-set</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'set-by-extension</span>
<span class="w"> </span><span class="ss">:ext</span><span class="w"> </span><span class="p">(</span><span class="nb">remove-if-not</span><span class="w"> </span><span class="p">(</span><span class="nv">predicate</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">enumeration</span><span class="w"> </span><span class="nv">b</span><span class="p">))))</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="p">))</span>
<span class="w"> </span><span class="c1">;; In diesem Fall wird aus den beiden Prädikaten von a und</span>
<span class="w"> </span><span class="c1">;; b ein neues Prädikat durch UND-Verknüpfung zusammengesetzt und</span>
<span class="w"> </span><span class="c1">;; die Ergebnis-Instanz der Klasse SET-BY-INTENSION damit</span>
<span class="w"> </span><span class="c1">;; initialisiert:</span>
<span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'set-by-intension</span>
<span class="w"> </span><span class="ss">:predicate</span><span class="w"> </span><span class="p">(</span><span class="k">lambda</span><span class="w"> </span><span class="p">(</span><span class="nv">x</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">and</span><span class="w"> </span><span class="p">(</span><span class="nb">funcall</span><span class="w"> </span><span class="p">(</span><span class="nv">predicate</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="nv">x</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">funcall</span><span class="w"> </span><span class="p">(</span><span class="nv">predicate</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="nv">x</span><span class="p">)))))</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">enumerateable-set</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">intersection2</span><span class="w"> </span><span class="nv">b</span><span class="w"> </span><span class="nv">a</span><span class="p">))</span><span class="w"> </span><span class="c1">; Rückführung auf den kommutativen Fall</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">enumerateable-set</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">enumerateable-set</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'set-by-extension</span>
<span class="w"> </span><span class="ss">:ext</span><span class="w"> </span><span class="p">(</span><span class="nb">intersection</span><span class="w"> </span><span class="p">(</span><span class="nv">enumeration</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">enumeration</span><span class="w"> </span><span class="nv">b</span><span class="p">))))</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Methode_der_generischen_Funktion_intersection2_für_Aufrufe_mit_zwei_Parametern_der_Klasse_integer-range-set"><span id="Methode_der_generischen_Funktion_intersection2_f.C3.BCr_Aufrufe_mit_zwei_Parametern_der_Klasse_integer-range-set"></span>Methode der generischen Funktion intersection2 für Aufrufe mit zwei Parametern der Klasse integer-range-set</h5></div>
<p>Obwohl dieser Fall schon durch die vierte Methode oben abgedeckt ist, bietet es sich hier an, eine spezifischere Methode vorzusehen um wieder ein Ergebnis der Klasse <code>integer-range-set</code> zu erhalten, da deren Darstellung kompakter ist.
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">integer-range-set</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">integer-range-set</span><span class="p">))</span>
<span class="w"> </span><span class="c1">;; Es wird das Maximum N der unteren und das Minimum M der</span>
<span class="w"> </span><span class="c1">;; Obergrenzen gebildet. Falls nun N&gt;M gilt, ist die Schnittmenge</span>
<span class="w"> </span><span class="c1">;; leer, sonst eine Instanz der Klasse INTEGER-RANGE-SET mit den</span>
<span class="w"> </span><span class="c1">;; Grenzen N und M</span>
<span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">((</span><span class="nv">n</span><span class="w"> </span><span class="p">(</span><span class="nb">max</span><span class="w"> </span><span class="p">(</span><span class="nv">from</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">from</span><span class="w"> </span><span class="nv">b</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">m</span><span class="w"> </span><span class="p">(</span><span class="nb">min</span><span class="w"> </span><span class="p">(</span><span class="nv">to</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">to</span><span class="w"> </span><span class="nv">b</span><span class="p">))))</span>
<span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">&gt;</span><span class="w"> </span><span class="nv">n</span><span class="w"> </span><span class="nv">m</span><span class="p">)</span>
<span class="w"> </span><span class="nv">empty-set</span>
<span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'integer-range-set</span><span class="w"> </span><span class="ss">:from</span><span class="w"> </span><span class="nv">n</span><span class="w"> </span><span class="ss">:to</span><span class="w"> </span><span class="nv">m</span><span class="p">))))</span>
</pre></div>
<div class="mw-heading mw-heading5"><h5 id="Zusätzliche_Methoden_für_die_generische_Funktion_intersection2_für_den_Umgang_mit_der_leeren_Menge"><span id="Zus.C3.A4tzliche_Methoden_f.C3.BCr_die_generische_Funktion_intersection2_f.C3.BCr_den_Umgang_mit_der_leeren_Menge"></span>Zusätzliche Methoden für die generische Funktion intersection2 für den Umgang mit der leeren Menge</h5></div>
<div style="font-size:90%; float:right; margin-left:2em; width:25%; border:1px solid #448800; padding:0.4em; background:#EEFFEE; margin-bottom:3em;">
<p><b>Common-Lisp:</b> Der <code>eql</code>-Specializer
</p><p>Common Lisp kann Methoden einer generischen Funktion nicht nur auf Klassen spezialisieren, sondern auch auf eine einzelne Instanz. Dazu wird als Typ des Parameters nicht eine Klasse angegeben, sondern der Ausdruck <code>(eql &lt;instanz&gt;)</code>. Wenn die zugehörige generische Funktion nun mit genau dieser Instanz aufgerufen wird, dann ist diese Methode <i>spezifischer</i> als eine, die an der gleichen Position mit einer passenden Klasse definiert wurde und wird statt dieser aufgerufen.
</p>
</div>
<p>Mit den folgenden beiden Methoden wird durch Verwendung eines <code>eql</code>-Specializers (siehe Box) erreicht, dass die Schnittmenge aus der leeren Menge und einer beliebigen Menge ohne weitere Untersuchung die leere Menge selbst ist:
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="p">(</span><span class="nb">eql</span><span class="w"> </span><span class="nv">empty-set</span><span class="p">))</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="nv">any-set</span><span class="p">))</span>
<span class="w"> </span><span class="nv">empty-set</span><span class="p">)</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nv">intersection2</span><span class="w"> </span><span class="p">((</span><span class="nv">a</span><span class="w"> </span><span class="nv">any-set</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">b</span><span class="w"> </span><span class="p">(</span><span class="nb">eql</span><span class="w"> </span><span class="nv">empty-set</span><span class="p">)))</span>
<span class="w"> </span><span class="nv">empty-set</span><span class="p">)</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="print-object-Methoden">print-object-Methoden</h4></div>
<p>Mit obigen Definitionen ist die Funktionalität vollständig umgesetzt. Um den Dialog mit Common Lisp zu vereinfachen, erfolgt nun noch die Definition von geeigneten Methoden für die durch das System vordefinierte Generische Funktion <code>print-object</code>, die das Lisp-System zur Darstellung der Mengen bei der Ausgabe heranzieht.
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nb">print-object</span><span class="w"> </span><span class="p">((</span><span class="nv">s</span><span class="w"> </span><span class="nv">set-by-extension</span><span class="p">)</span><span class="w"> </span><span class="nc">stream</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">prin1</span><span class="w"> </span><span class="p">(</span><span class="nv">ext</span><span class="w"> </span><span class="nv">s</span><span class="p">)</span><span class="w"> </span><span class="nc">stream</span><span class="p">))</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nb">print-object</span><span class="w"> </span><span class="p">((</span><span class="nv">s</span><span class="w"> </span><span class="nv">set-by-intension</span><span class="p">)</span><span class="w"> </span><span class="nc">stream</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">format</span><span class="w"> </span><span class="nc">stream</span><span class="w"> </span><span class="s">"~A"</span><span class="w"> </span><span class="p">(</span><span class="nb">function-lambda-expression</span><span class="w"> </span><span class="p">(</span><span class="nv">predicate</span><span class="w"> </span><span class="nv">s</span><span class="p">))))</span>

<span class="p">(</span><span class="nb">defmethod</span><span class="w"> </span><span class="nb">print-object</span><span class="w"> </span><span class="p">((</span><span class="nv">s</span><span class="w"> </span><span class="nv">integer-range-set</span><span class="p">)</span><span class="w"> </span><span class="nc">stream</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">format</span><span class="w"> </span><span class="nc">stream</span><span class="w"> </span><span class="s">"(~A .. ~A)"</span><span class="w"> </span><span class="p">(</span><span class="nv">from</span><span class="w"> </span><span class="nv">s</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">to</span><span class="w"> </span><span class="nv">s</span><span class="p">)))</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Anwendungsbeispiel">Anwendungsbeispiel</h3></div>
<div style="font-size:90%; float:right; margin-left:2em; width:25%; border:1px solid #448800; padding:0.4em; background:#EEFFEE; margin-bottom:3em;">
<p><b>Common-Lisp:</b> <code>(loop … )</code>
</p><p>Das Makro <code>loop</code> ist ein mächtiges Iterationsmittel. <code>loop</code>-Schleifen können zumeist ganz naiv gelesen werden, um ihren Inhalt zu erfassen. Das Beispiel links kann so übersetzt werden:
</p>
<ul><li>„n ist eine Primzahl, wenn für jede natürliche Zahl von 2 bis zur Wurzel aus n gilt, dass der Divisionsrest von n/i niemals 0 ist“</li></ul>
<p>Davor ist noch die Bedingung <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle n>1}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>n</mi>
<mo>&gt;</mo>
<mn>1</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle n&gt;1}</annotation>
</semantics>
</math></span><img src="./_assets_/eb734a37dd21ce173a46342d1cc64c92/ee74e1cc07e7041edf0fcbd4481f5cd32ad17b64.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:5.656ex; height:2.176ex;" alt="{\displaystyle n>1}" loading="lazy"></span> gesetzt, da die Zahl 1 im mathematischen Sinn keine Primzahl ist.
</p>
</div>
<p>Die Gesamtfunktionalität ist aus folgendem Anwendungsbeispiel ersichtlich.
</p><p>Die Menge aller Primzahlen kann durch das Prädikat <code>prime</code> dargestellt werden.
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">prime</span><span class="w"> </span><span class="p">(</span><span class="nv">n</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">when</span><span class="w"> </span><span class="p">(</span><span class="nb">&gt;</span><span class="w"> </span><span class="nv">n</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nb">loop</span><span class="w"> </span><span class="nv">for</span><span class="w"> </span><span class="nv">i</span><span class="w"> </span><span class="nv">from</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="nv">to</span><span class="w"> </span><span class="p">(</span><span class="nb">isqrt</span><span class="w"> </span><span class="nv">n</span><span class="p">)</span>
<span class="w"> </span><span class="nv">never</span><span class="w"> </span><span class="p">(</span><span class="nb">eql</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">(</span><span class="nb">mod</span><span class="w"> </span><span class="nv">n</span><span class="w"> </span><span class="nv">i</span><span class="p">)))))</span>
</pre></div>
<p>Mit dieser Definition als Prädikat ist es jetzt möglich, die Menge aller Primzahlen <code>set-of-primes</code> als Instanz von <code>set-by-intension</code> zu konstruieren:
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">set</span><span class="w"> </span><span class="ss">'set-of-primes</span><span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'set-by-intension</span>
<span class="w"> </span><span class="ss">:predicate</span><span class="w"> </span><span class="nf">#'</span><span class="nv">prime</span><span class="p">))</span>
</pre></div>
<p>Als zweite Menge fungiert die Menge <code>first-100</code> der ganzen Zahlen von 1 bis 100:
</p>
<div style="width:65%" class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nb">set</span><span class="w"> </span><span class="ss">'first-100</span><span class="w"> </span><span class="p">(</span><span class="nb">make-instance</span><span class="w"> </span><span class="ss">'integer-range-set</span><span class="w"> </span><span class="ss">:from</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="ss">:to</span><span class="w"> </span><span class="mi">100</span><span class="p">))</span>
</pre></div>
<p>Die Schnittmenge beider Mengen, also die Primzahlen von 1 bis 100, kann dann jetzt durch den Aufruf der Generischen Funktion <code>intersection2</code> berechnet werden:
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="nv">intersection2</span><span class="w"> </span><span class="nv">set-of-primes</span><span class="w"> </span><span class="nv">first-100</span><span class="p">)</span>
</pre></div>
<p>Es erfolgt die korrekte Ausgabe
</p>
<div class="mw-highlight mw-highlight-lang-lisp mw-content-ltr" dir="ltr"><pre><span></span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="mi">13</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="mi">19</span><span class="w"> </span><span class="mi">23</span><span class="w"> </span><span class="mi">29</span><span class="w"> </span><span class="mi">31</span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="mi">41</span><span class="w"> </span><span class="mi">43</span><span class="w"> </span><span class="mi">47</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="mi">59</span><span class="w"> </span><span class="mi">61</span><span class="w"> </span><span class="mi">67</span><span class="w"> </span><span class="mi">71</span><span class="w"> </span><span class="mi">73</span><span class="w"> </span><span class="mi">79</span><span class="w"> </span><span class="mi">83</span><span class="w"> </span><span class="mi">89</span><span class="w"> </span><span class="mi">97</span><span class="p">)</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Erläuterung"><span id="Erl.C3.A4uterung"></span>Erläuterung</h3></div>
<ul><li>Am Methodenaufruf ist keine einzelne aufrufende Instanz syntaktisch erkennbar, da alle Parameter gleich behandelt werden. Es gibt kein implizites <code>this</code>, oder ähnliches.</li>
<li>Methoden werden in Common Lisp nie direkt aufgerufen, sondern ausschließlich auf dem Umweg über die generische Funktion gleichen Namens.</li>
<li>Die generische Funktion führt den Dispatch auf „eingehängten“ Methoden durch. Dazu ermittelt sie zunächst eine nach Spezifität sortierte Liste der <i>anwendbaren Methoden</i> und ruft die Methode mit der höchsten Spezifität auf. Anwendbar sind dabei alle Methoden, deren formale Parameter entweder den Klassen der aktuellen Parameter entsprechen oder direkt oder indirekt deren Elternklasse sind.</li>
<li>Wird die Deklaration der generischen Funktion weggelassen, so erledigt Common Lisp das selbst, sobald die erste Methodendefinition erfolgt.</li>
<li>Die Vererbungsmechanismen innerhalb der Klassenhierarchie bezüglich der Slots („Membervariablen“) arbeiten wie bei eindimensionaler objektorientierter Programmierung.</li>
<li>In diesem Beispiel wird das Common Lisp Object System (CLOS) nur so weit vorgestellt, wie dies zum Verständnis von Multimethoden erforderlich ist. Der Funktionsumfang von CLOS geht erheblich weiter.</li>
<li>Multimethoden können die eindimensionale objektorientierte Programmierung vollständig darstellen, aber nicht umgekehrt.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Literatur">Literatur</h2></div>
<ul><li><style data-mw-deduplicate="TemplateStyles:r261891140">
/* start https://de.wikipedia.org/ */


.mw-parser-output .webarchiv-memento a{color:inherit}


/* end https://de.wikipedia.org/ */
</style><a rel="nofollow" class="external text" href="https://web.archive.org/web/20090927003121/http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+INCITS+226-1994+(R2004)"><i>Common Lisp Standard – ANSI INCITS 226-1994 (R2004)</i></a> (<span class="webarchiv-memento"><a href="Webarchivierung#Begrifflichkeiten" title="Webarchivierung">Memento</a></span> vom 27. September 2009 im <i><a href="Internet_Archive" title="Internet Archive">Internet Archive</a></i>)</li>
<li>Patrick M. Krusenotto <i>Funktionale Programmierung und Metaprogrammierung – Interaktiv in Common Lisp</i> Springer 2016, ISBN 978-3-658-13743-4.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Weblinks">Weblinks</h2></div>
<ul><li><a rel="nofollow" class="external text" href="https://www.lispworks.com/documentation/HyperSpec/Front/index.htm">Common Lisp HyperSpec</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Einzelnachweise">Einzelnachweise</h2></div>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external text" href="https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node260.html#SECTION003200000000000000000"><i>Common Lisp – The Language.</i></a> 2nd Edition.</span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external text" href="https://groovy-lang.org/differences.html">Groovy - Multi-methods</a></span>
</li>
</ol></div><!--htdig_noindex--><div><div class="zim-footer">
Dieser Artikel wurde von <a class="external text" title="Zuletzt bearbeitet am 2025-06-25" href="https://de.wikipedia.org/wiki/?title=Multimethode&amp;oldid=257349726">Wikipedia</a> herausgegeben. Der Text ist unter <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.de">Creative Commons Attribution-Share Alike 4.0</a> verfügbar, sofern nicht anders angegeben. Für die Mediendateien können zusätzliche Bedingungen gelten.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="./_webp_/webpHandler.js"></script>

</body></html>